﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BehaviorFramework;
using System.Windows;
using System.Timers;
using System.Windows.Threading;
using System.Collections.ObjectModel;
using System.Diagnostics;

namespace WpfTestApplication
{
    /// <summary>
    /// The So-Called BehaviorClass represents additional behavior that will be combined with my data class to 
    /// produce the ViewModel  In the below sample, I add a NameAge, and Birthdate that are readonly
    /// Also I add a list of addresses, and an AlertNameAge BehaviorCommand that can execute when the name = Lance
    /// Lastly, I added a timer to increment the age every 5 seconds.
    /// </summary>
    public class BehaviorClass : BehaviorInjector<Dataclass>
    {
		public BehaviorClass()
		{
			InitBehavior();
		}

		public BehaviorClass(Dataclass dataclass)
			: base(dataclass)
		{
			InitBehavior();
		}

		private void InitBehavior()
		{
			//Add a list of addresses, an observable collection allows us to track changes. Need to figure out how to make these work like the observable properties
			//so it can wrap a non observable list, and track changes maybe..
			//ViewModel.Addresses = new ObservableCollection<string>{
			//    "Address1","Address2","Address3"
			//};

			//Another way to implement a command in the viewmodel, with control of the canexecute.
			ViewModel.AlertNameAge1 = new BehaviorCommand(
					execute: (nameAge) =>
					{
						MessageBox.Show(string.Format("Command from behavior class {0} {1}'s NameAge is: {2}", ViewModel.Name, ViewModel.LastName, ViewModel.Age));
					},
					canExecute: (nameAge) =>
					{
						return ViewModel.Age % 2 == 0;// != "Lance";
					});

			//Set a timer to increment the age...just for fun...
			var t = new Timer()
			{
				AutoReset = false,
				Interval = 2000,
				Enabled = true,
			};
			var disp = Dispatcher.CurrentDispatcher;

			t.Elapsed += (e, a) =>
			{
				ViewModel.Age++;
				ViewModel.BirthDate = DateTime.Now.AddYears(ViewModel.Age);
				ViewModel.FavoriteColor = "Color" + ViewModel.Age;
				disp.InvokeIfRequired(() => ViewModel.Addresses.Add("Address" + ViewModel.Age)); t.Start();
			};
		}
		
		public string NameAge
        {
            get
            {
                return string.Format("{0} - Age: {1}", ViewModel.Name, ViewModel.Age);
            }
        }

        public string NameAgeSerialNumber
        {
            get
            {
                return string.Format("{0} - Age: {1} - {2}", ViewModel.Name, ViewModel.Age, DateTime.Now.Millisecond);
            }
        }

        /// <summary>
        ///Decorating a method that has 0 or 1 parameter will expose it as an ICommand in the ViewModel
        ///If a CanExecuteMethodName is not specified, it will look for a method called "Can" + the name of the method
        ///If the Can method is not found or specified, it will always be executable.
        ///</summary>   
        [UseCommandBehavior()]
        public void AlertNameAge()
        {
            MessageBox.Show(string.Format("Command From Behavior using UseCommandBehavior Attribute: {0} {1}'s NameAge is: {2}", ViewModel.Name, ViewModel.LastName, ViewModel.Age));
        }

        public bool CanAlertNameAge()
        {
            return ViewModel.Age % 3 == 1;
        }

        /// <summary>
        /// You can specify a CanExecute Method by name in the UseCommandBehavior attribute.
        /// </summary>
        [UseCommandBehavior("CanAlertNameAge")]
        public void AlertNameAge2()
        {
            MessageBox.Show(string.Format("Command From Behavior using UseCommandBehavior Attribute with CanExecuteMethod Specified: {0} {1}'s NameAge is: {2}", ViewModel.Name, ViewModel.LastName, ViewModel.Age));
        }

    }
}
